#include "PresenceNotifierService_types.h"
#include "PresenceNotifierService.h"

#include "melon/service/service_arch.h"
#include "melon/service/base_service_impl.h"
#include "base/logging.h"
#include "base/get_local_ip.h"
#include "base/config_reader.h"

#include "notify_presence_task.h"
#include "notify_typing_task.h"

namespace imserver {

class PresenceNotifierServiceHandler : public PresenceNotifierServiceIf, public melon::service::BaseServiceImpl {
 public:
  PresenceNotifierServiceHandler() {
  }
  virtual void SessionChanged(const int64_t uid, const std::string& session, const SessionType::type type) {
    LOG_INFO("SessionChanged uid=" << uid << " session=" << session << " type=" << type);
    using apache::thrift::concurrency::Runnable;
    GetThreadManager()->add(boost::shared_ptr<Runnable>(new NotifyPresenceTask(uid, session, type)));
  }
  virtual void UserTyping(const int64_t sender, const int64_t receiver) {
    LOG_INFO("UserTyping sender=" << sender << " receiver=" << receiver);
    using apache::thrift::concurrency::Runnable;
    GetThreadManager()->add(boost::shared_ptr<Runnable>(new NotifyTypingTask(sender, receiver)));
  }
};

}

int main(int argc, char **argv) {
  char * conf_file = "../conf/presence_notifier_service.conf";
  char opt;
  while ((opt = getopt(argc, argv, "c:")) != -1) {
    switch (opt) {
    case 'c':
      conf_file = optarg;
      break;
    default:
      std::cerr << "Unknown option " << optopt << std::endl;
      return 1;
    }
  }

  ConfigReader cfg(conf_file);
  if (!cfg) {
    std::cerr << "Config file " << conf_file << " read error!" << std::endl;
    return 1;
  }

  LOG_INIT(cfg.Get("log4cplus", "file"), cfg.Get("log4cplus", "level"));

  int port = cfg.GetWithType<int>("presence_notifier_service", "port", 9097);
  LOG_INFO("listens on port " << port);

  using namespace imserver;
  melon::service::ThriftService<PresenceNotifierServiceHandler, PresenceNotifierServiceProcessor> service;
  service.StartRegister("/im/presence_notifier_service", "1.0", 0, base::GetLocalIp(), port, 1);
  service.Start(port);
  return 0;
}

